const {getDmg,reduceResistanceK,lvSuppressK,objValueAdd } = require("../libs/apis.js")

const WEAPONS = require("./weapons.js");

const CLIPDATA_TYPE = {
    max:{
        fixedhp: 298.75,
        fixedAtt: 19.45,
        fixdefence: 23.15,
        reaction : 23.31,
        attRate: 5.83, 
        hpRate: 5.83, 
        criticalRate: 3.89,
        criticalStrike: 7.77,
        defRate: 7.29,
        charging: 6.48
    },
    mid:{
        fixedhp: 253.94,   // 209.13  239   268.88   298.75
        fixdefence: 19.675, // 16.2   18.52  20.83  23.15
        fixedAtt: 16.535,   //  13.62   15.56   17.51  19.45
        reaction : 19.815,  // 16.32   18.65  20.98  23.31
        attRate: 4.955,  // 4.08  4.66  5.25  5.83
        hpRate: 4.955,   // 4.08  4.66  5.25  5.83
        criticalRate: 3.305,   //  2.72  3.11   3.5   3.89
        criticalStrike: 6.605,  //  5.44  6.22  6.99  7.77
        defRate: 6.195,   //  5.1  5.83  6.56   7.29
        charging: 5.505  //  4.53   5.18   5.83   6.48
    }
}

const CLIPDATA = CLIPDATA_TYPE.mid

const CONFIG = {
    chance: 4,
    your_lv: 90,
    enemy_lv: 90,
    clips_main: {
        fixedHp: 4780,
        fixedAtt:311,
        hpRate: 46.6 * 3,
        // reaction: 187,
        // dmgRate: 46.6,
        // criticalRate: 31.1,
    },
    clips_initial: [
        ["reaction", "hpRate", "criticalRate", "criticalStrike"],
        ["reaction", "hpRate", "criticalRate", "criticalStrike"],
        ["charging", "reaction", "criticalRate", "criticalStrike"],
        ["charging", "reaction", "criticalRate", "criticalStrike"],
        ["criticalRate", "reaction", "charging", "criticalStrike"]
    ],
    reactionK : 2,
    reactionDmgAdd: 0,
    buffs: [  
        { reaction: 80, hpRate: 20},  // 2+2
        { reaction: 120 }, // 教官
        { reaction: 80 }, // 双草
        { hpRate: 20 } // 水
    ]
}

let charaters = {
    units : {
        name: "妮露", 
        dmgZhi: 0,
        reaction: 100,
        charging: 100,
        dmgRate: 0,
        defRate: 0,
        defence: 728.59,
        weapontype: "sword",
        hpRate:28.8,
        attRate: 0,
        hp:15185,
        base: 229.61,    
        criticalRate: 5,    
        criticalStrike: 50,
        skills: {
            a: [
                function(data){},
            ]
        }
    },
}

let tmp = {}
CONFIG.clips_initial.forEach(item => {
    item.forEach(item2 => {
        if(tmp[item2]) {
            tmp[item2] += 1
        } else {
            tmp[item2] = 1
        }
    })
})
/*
 面板： 血15185  白字229.6 双爆5/50 生命:28.8%
 e 七域舞步 
 lv10 0.0601   0.0819/0.0587  0.0926/0.0713  0.129/0.0911
 lv13 0.0701   0.0967/0.0693  0.1093/0.0842  0.1523/0.1076

 q 2段
 lv10  0.4424 + 0.5407   lv13  0.5222 + 0.6383

 天赋
 e三段后 全队金杯的丰馈 触发绽放后释放 丰壤之核
 超过30000的hp 每1000点 给 丰壤之核增伤7% 最高 300%


 1 水月增伤 65
 2 降低敌人35 水草抗性
 3 q+3
 4 3段舞步后回15能 大招增伤50
 5 e+3
 6 每1000hp + 0.6/1.2 双爆 最高+ 30/60

 暴击期望伤害  
 0命1精专武 2+2(80精通 20生命) 生生生  (草系带草套降低敌人30草抗)
    剑舞步1段 3006  剑舞步2段 3399  水月 4735
    q1段 16240  q2段 19849  丰壤之核绽放 27734
 2命1精专武 2+2(80精通 20生命) 生生生  (草系带草套降低敌人30草抗)
    剑舞步1段 3758  剑舞步2段 4249  水月 9767
    q1段 20300  q2段 24811  丰壤之核绽放 32147
 2命1精专武 2+2(80精通 20生命) 生草爆  (草系带草套降低敌人30草抗)
    剑舞步1段 6841  剑舞步2段 7735  水月 15554
    q1段 36956  q2段 45168  丰壤之核绽放 24620
 满命1精专武 2+2(80精通 20生命) 生草爆  (草系带草套降低敌人30草抗)
    剑舞步1段 13284  剑舞步2段 15015  水月 30199
    q1段 96205  q2段 117595  丰壤之核绽放 22475
  
 舍弃丰壤之核打水伤
    0命1精专武 2+2(80精通 20生命) 生草爆
    剑舞步1段 5988  剑舞步2段 6770  水月 9431  水月蒸发 34047
    q1段 32345  q2段 39533 q1段蒸发 116763  q2段蒸发 142707 
 
    2命1精专武 2+2(80精通 20生命) 生草爆
    剑舞步1段 7485  剑舞步2段 8463  水月 17017 水月蒸发 61428
    q1段 40432  q2段 49416 q1段蒸发 145953  q2段蒸发 178384 

    满命1精专武 2+2(80精通 20生命) 生草爆  (草系带草套降低敌人30草抗)
    剑舞步1段 13373  剑舞步2段 15115  水月 30401 水月蒸发 109485
    q1段 96849  q2段 118381  q1段蒸发 348788  q2段蒸发 426333
*/

let cons = 0
let consData = {
    syDmgAdd : 0,
    jk : 0,
    qDmgAdd : 0,
    sbflag: false
}
if(cons >= 1) {
    consData.syDmgAdd = 65
}
if(cons >= 2) {
    consData.jk = 35
}
if(cons >= 3) {
    consData.qadd = 3
}
if(cons >= 4) {
    consData.qDmgAdd = 50
}
if(cons >= 5) {
    consData.eadd = 3
}
if(cons >= 6) {
    consData.sbflag = true
}



let cid = "units"
let count_kit = 0;
let combination = getCombination(Array(5*CONFIG.chance + 1).fill().map((_,i)=>i), CONFIG.chance, Object.entries(tmp))
let clips_initial_data = calc_clips_initial()
let fs = require("fs")
calc(combination);
function calc(clipSecondData) {
    let charactersDmg = [];
    clipSecondData = clipSecondData.map(clipSecondDataItem => {
        let clipSecond = {}
        clipSecond.des = clipSecondDataItem;
        clipSecond.data = {} 
        for (let secondKey in clipSecond.des) {
            let count =  clipSecond.des[secondKey]
            clipSecond.data[secondKey] = count * CLIPDATA[secondKey]
        }
        return clipSecond
    })
    
    Object.values(WEAPONS).forEach(weapon => {
        if(charaters[cid].weapontype && weapon.weapontype != charaters[cid].weapontype && weapon.weapontype!="all") {return}
        charactersDmg.push(getDMG([charaters[cid],weapon,clips_initial_data,{...CONFIG.clips_main}], clipSecondData, (data,second) => {
            count_kit++;
            data = objValueAdd([data, ...CONFIG.buffs]);
            data.hp = data.hp*(1 + (data.hpRate||0)/100) + data.fixedHp;
            data.reaction += 100
            
            if(weapon.skill) { weapon.skill(data); }
            let crAdd = Math.floor(data.hp/1000) * 0.6
            let csAdd = Math.floor(data.hp/1000) * 1.2
            if(crAdd > 30) {
                crAdd = 30
            } 
            if(csAdd > 60) {
                csAdd = 60
            } 
            if(consData.sbflag) {
                data.criticalRate += crAdd
                data.criticalStrike += csAdd
            }
            
            let eRate = [0.0601, 0.0819, 0.0926, 0.129]
            if(cons >= 5) {
                eRate = [0.0701,0.0967,0.1093,0.1523]
            }

            let rea = { reaction:data.reaction, reactionQ:CONFIG.reactionK, reactionDmgAdd:data.reactionDmgAdd || 0 }

            // 七域舞步  剑舞步
            // lv10 0.0601   0.0819/0.0587  0.0926/0.0713  0.129/0.0911
            let eDmg = getDmg({ data:{
                ...data, dmgZhi: data.dmgZhi + data.hp*eRate[0]
            }, rate:0}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let j1Dmg = getDmg({ data:{
                ...data, dmgZhi: data.dmgZhi + data.hp*eRate[1]
            }, rate:0}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let j2Dmg = getDmg({ data:{
                ...data, dmgZhi: data.dmgZhi + data.hp*eRate[2]
            }, rate:0}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let syDmg = getDmg({ data:{ // 水月
                ...data, dmgZhi: data.dmgZhi + data.hp*eRate[3],
                dmgRate: data.dmgRate + consData.syDmgAdd
            }, rate:0}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let syDmgzf = getDmg({ data:{ // 水月
                ...data, dmgZhi: data.dmgZhi + data.hp*eRate[3],
                dmgRate: data.dmgRate + consData.syDmgAdd
            }, rate:0,rea}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            // 0.0701   0.0967/0.0693  0.1093/0.0842  0.1523/0.1076
            // lv10  0.4424 + 0.5407 
            // 0.5222 + 0.6383
            let qRate = [0.4424,0.5407]
            if(cons >= 5) {
                qRate = [0.5222,0.6383]
            }
            let q1Dmg = getDmg({ data:{ // 
                ...data, dmgZhi: data.dmgZhi + data.hp*qRate[0],
                dmgRate: data.dmgRate + consData.qDmgAdd
            }, rate:0}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let q2Dmg = getDmg({ data:{ // 
                ...data, dmgZhi: data.dmgZhi + data.hp*qRate[1],
                dmgRate: data.dmgRate + consData.qDmgAdd
            }, rate:0}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let q1DmgZf = getDmg({ data:{ // 
                ...data, dmgZhi: data.dmgZhi + data.hp*qRate[0],
                dmgRate: data.dmgRate + consData.qDmgAdd
            }, rate:0,rea}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);
            let q2DmgZf = getDmg({ data:{ // 
                ...data, dmgZhi: data.dmgZhi + data.hp*qRate[1],
                dmgRate: data.dmgRate + consData.qDmgAdd
            }, rate:0,rea}).qw * reduceResistanceK(10-consData.jk) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);

            // 丰壤之核
            let frzs = 0;
            if(data.hp > 30000) {
                frzs = 0.09 * Math.floor((data.hp-30000)/1000)
                if(frzs > 4) {frzs = 4}
            }
            let aft = data.reaction * 16 / (2000 + data.reaction)
            let fr = 723.5 * 4 * (aft + 1 + frzs) * reduceResistanceK(10-consData.jk-30)

            if(data.phyRate) { // 物理特效伤害
                data.phyDmg = getDmg({data:{...data, dmgRate:0}, rate:data.phyRate}).qw * reduceResistanceK(10) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);  // 
            }

            let point = eDmg + (j1Dmg + j2Dmg +  syDmg) * 3 + q1DmgZf + q2DmgZf + fr*25 + (data.phyDmg||0);
            let attack = data.base *(1 + data.attRate/100) + data.fixedAtt;
            return {point, data, second, attack, dmg:{j1Dmg,j2Dmg,syDmg,q1Dmg,q2Dmg,fr,frzs,q1DmgZf,q2DmgZf,syDmgzf}}
        }))
    })
    
    charactersDmg.sort((a,b)=>{
        return (b.point)-(a.point);
    });
    let sortf = JSON.parse(fs.readFileSync("./sort.js").toString()) 
    let choose = charactersDmg[1];
    console.log(choose);

    let name = choose.data.name
    let keys = "_"+choose.data.weaponname+"_6命无拐2+2毕业"
    let sortfData = {key: name+keys, point:choose.point, dmg:JSON.parse(JSON.stringify(choose.dmg))}
    if(sortfData.point && sortfData.point > 0) {
        let org = sortf.findIndex(item3 => item3.key == sortfData.key)
        if(org >= 0){
            sortf[org] = sortfData
        } else {
            sortf.push(sortfData)
        }
        sortf.sort((b,a) => a.point-b.point)
        // fs.writeFileSync("./sort.js", JSON.stringify(sortf))
    }
    console.log(charactersDmg.map((v, n)=>{
        return  `(${n})得分: ${v.data.weaponname} : ${v.point.toFixed(0)}`
    }));
    console.log(count_kit);
}

function getDMG(dataarr, clipSecond, getRet){
    clipSecond = clipSecond.map(second => {
        let panel = objValueAdd([...dataarr, second.data]);
        return  getRet(panel, second)
    })
    clipSecond.sort((b,a)=> a.point-b.point)
    return clipSecond[0]
}

function calc_clips_initial () {
    let clips = CONFIG.clips_initial.map(v => {
        let tmp = {};
        v.forEach(v2 => {
            tmp[v2] = CLIPDATA[v2]
        })
        return tmp
    })
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}
function getCombination (arr, chance, entrys) {
    let num = 5
    var r = [];
    (function f(t, a, n) {
        if (n === 0) {
            if(t.reduce((a1,b1) => a1+b1) !== chance * 5){return}
            let ret = {}
            for (let i in t) {
                if(t[i] > entrys[i][1]*chance){return}
                ret[entrys[i][0]] = t[i]
            }
            r.push(ret)
            return ;
        }
        for (var i = 0, l = a.length; i < l; i++) {
            f(t.concat(a[i]), a, n - 1);
        }
    })([], arr, num);
    return r;
}